from decimal import Decimal

import logging
from django.db import transaction
from django.utils import timezone
from rest_framework import serializers

from carts.utils import ReadWriteTool
from goods.models import SKU
from orders.models import OrderInfo, OrderGoods



logger = logging.getLogger('django')

class SkuSerializer(serializers.ModelSerializer):
    count = serializers.IntegerField(label='购买数量')

    class Meta:
        model = SKU
        fields = ['id', 'name', 'default_image_url', 'price', 'count']


class GetOrderSerializer(serializers.Serializer):
    freight = serializers.DecimalField(label='运费', max_digits=10, decimal_places=2)
    skus = SkuSerializer(many=True)


class SaveOrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ['address', 'pay_method', 'order_id']
        extra_kwargs = {
            'order_id': {
                'read_only': True
            },
            'address': {
                'write_only': True,
                'required': True
            },
            'pay_method': {
                'write_only': True,
                'required': True
            }
        }

    def create(self, validated_data):
        user = self.context['request'].user
        order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)
        address = validated_data.get('address')
        pay_method = validated_data.get('pay_method')
        freight = Decimal('10.00')
        total_count = 0
        status = OrderInfo.UNSEND if pay_method == OrderInfo.CASH else OrderInfo.UNPAID

        tool = ReadWriteTool()
        carts_dict = tool.read_from_redis(user.id)  # 读取购物车数据
        # carts_dict = {'sku_id':[1,True],'sku_id2':[2,False]}

        with transaction.atomic():  # 开启事务

            save_id = transaction.savepoint()
            try:
                # 创建订单详情数据
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=total_count,
                    total_amount=Decimal(0),
                    freight=freight,
                    pay_method=pay_method,
                    status=status
                    )
                # 查询库存 删库存 加销量

                sku_id_list = carts_dict.keys()
                for sku_id in sku_id_list:
                    if carts_dict[sku_id][1] is True:
                        # 判断库存
                        sku = SKU.objects.get(id=sku_id)
                        if sku.stock < carts_dict[sku.id][0]:
                            # 回滚到保存点
                            transaction.savepoint_rollback(save_id)
                            raise serializers.ValidationError('商品%s库存不足' % sku.name)
                        while True:
                            # 减库存 加销量
                            new_stock = sku.stock - carts_dict[sku.id][0]
                            new_sales = sku.sales + carts_dict[sku.id][0]

                            item = SKU.objects.filter(id=sku.id, stock=sku.stock).update(stock=new_stock, sales=new_sales)

                            if item == 0:
                                continue
                            # 创建订单商品信息
                            break

                        order.total_count += carts_dict[sku.id][0]
                        order.total_amount += (sku.price * carts_dict[sku.id][0])

                        OrderGoods.objects.create(
                            order=order,
                            sku=sku,
                            count=carts_dict[sku.id][0],
                            price=sku.price,
                        )

                order.save()
            except serializers.ValidationError:
                raise
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                raise
            else:
                transaction.savepoint_commit(save_id)

        # 4.删除购物车里面的商品
        cars_del_dict = {}
        for key, value in carts_dict.items():
            if not value[1]:
                cars_del_dict[key] = value

        print(cars_del_dict)

        tool.write_to_redis(user.id, cars_del_dict)

        return order